#ifndef __LIST_FIND_STU_CPP__
#define __LIST_FIND_STU_CPP__
#include "../include/list.h"


class Student;

template <>
std::wstring List<Student>::scanCommand() {
    std::wstring wstr, tmp;
    std::wcout << L"请输入查找条件: sname|sno|age|gender =|!=|<|<=|>|>= "
        L"{value}\nvalue 请用花括号 { } 包起来.\n"
        L"多个条件用空格分开, 若输入多个条件, 则需要同时满足.\n"
        L"花括号内不可输入 { } = 这些符号, 也不可输入空格.\n"
        L"例如: sname = {小明} gender = {其他}\n或者: age >= {18}\n\n>>> ";
    while (std::getline(std::wcin, tmp), !tmp.empty()) {
        std::wcout << L"(输入空行结束, 或继续输入) ";
        wstr.append(tmp).push_back(L' ');
    }
    wstr += L'}';
    return wstr;
}

/**
 * @brief 解析输入的内容为搜索指令.
 * @param wstr  [IN/OUT] 输入的字符串, 会修改原始内容.
 * @param wstrs [OUT] 字符串池, 搜索字符串数据需要使用.
 * @param code  [OUT] 搜索指令.
 * @param code[0]: \\x01"sname" \\x02"sno" \\x03"age" \\x04"gender"
 * @param code[1]: \\x11"=" \\x12"!=" \\x13"<" \\x14"<=" \\x15">" \\x16">="
 * @param code[2]: value, 是数字或者字符池的下标.
 */
template <>
void List<Student>::parse(
    std::wstring& wstr,
    std::vector<std::wstring>& wstrs,
    std::vector<int>& code) {

    // 删除花括号里的空格.
    for (int i = 0; i != wstr.length(); ++i) {
        if (wstr[i] == L'{') { for (int j = i + 1; j != wstr.length(); ++j) {
            if (wstr[j] == L'}') { for (int k = i + 1; k != j; ++k) {
                if (wstr[k] <= L'\x20') {
                    wstr.erase(k, 1);
                    --j; --k;
                }
            } i = j; break;}
        }}
    }
    // 删除连续空白符 和 '=' 和 "{}", 防止恶意输入
    wstr = std::regex_replace(wstr, std::wregex(LR">_<(\s+)>_<"                     ), L" ");
    wstr = std::regex_replace(wstr, std::wregex(LR">_<([ ]?(=|!=|<|<=|>|>=)[ ]?)>_<"), L"$1");
    wstr = std::regex_replace(wstr, std::wregex(LR">_<(=+)>_<"                      ), L"=");
    wstr = std::regex_replace(wstr, std::wregex(LR">_<(\{+)>_<"                     ), L"{");
    wstr = std::regex_replace(wstr, std::wregex(LR">_<(\}+)>_<"                     ), L"}");
    wstr = std::regex_replace(wstr, std::wregex(LR">_<(\{\})>_<"                    ), L"");
    // 替换"关键字"
    wstr = std::regex_replace(wstr, std::wregex(LR">_<(sname(=|!=|<|<=|>|>=)\{)>_<" ), L"\x01$1\{");
    wstr = std::regex_replace(wstr, std::wregex(LR">_<(sno(=|!=|<|<=|>|>=)\{)>_<"   ), L"\x02$1\{");
    wstr = std::regex_replace(wstr, std::wregex(LR">_<(age(=|!=|<|<=|>|>=)\{)>_<"   ), L"\x03$1\{");
    wstr = std::regex_replace(wstr, std::wregex(LR">_<(gender(=|!=|<|<=|>|>=)\{)>_<"), L"\x04$1\{");
    // 替换比较符
    wstr = std::regex_replace(wstr, std::wregex(LR">_<(([\x01-\x04])(=))>_<" ), L"$1\x11");
    wstr = std::regex_replace(wstr, std::wregex(LR">_<(([\x01-\x04])(!=))>_<"), L"$1\x12");
    wstr = std::regex_replace(wstr, std::wregex(LR">_<(([\x01-\x04])(<=))>_<"), L"$1\x14");
    wstr = std::regex_replace(wstr, std::wregex(LR">_<(([\x01-\x04])(<))>_<" ), L"$1\x13");
    wstr = std::regex_replace(wstr, std::wregex(LR">_<(([\x01-\x04])(>=))>_<"), L"$1\x16");
    wstr = std::regex_replace(wstr, std::wregex(LR">_<(([\x01-\x04])(>))>_<" ), L"$1\x15");

    // 匹配花括号里的字符串.
    std::wsmatch wsm;
    std::wstring::const_iterator __s = wstr.begin(), __e = wstr.end();
    std::wstring tmp;
    while (std::regex_search(__s, __e, wsm,
        std::wregex(LR">_<([\x01-\x04][\x11-\x16]\{[^\x00-\x20]+?\})>_<"))) {

        tmp = wsm[0];
        tmp.erase(0, 3).erase(tmp.end() - 1);
        wstrs.push_back(tmp);
        __s = wsm[0].second;
    }

    // mpos 是第几个 match.
    for (int i = 0, mpos = 0; i < wstr.length(); ++i) {
        if (wstr[i] == 1) {
            code.push_back(1);
            code.push_back(wstr[++i]);
            code.push_back(mpos++);
        }
        if (wstr[i] == 2 || wstr[i] == 3) {
            code.push_back(wstr[i]);
            code.push_back(wstr[++i]);
            code.push_back(stoi(wstrs[mpos++]));
        }
        if (wstr[i] == 4) {
            code.push_back(4);
            code.push_back(wstr[++i]);
            int gen = 0;
            tmp = wstrs[mpos++];
            if (tmp[0] < 128) {
                gen = tmp[0] & 1 ? 1 : 0;
            } else if (tmp == L"男") {
                gen = 1;
            } else if (tmp == L"女") {
            } else {
                gen = -1;
            }
            code.push_back(gen);
        }
    }

    code.push_back(0);
}

template class List<Student>;


#endif /* __LIST_FIND_STU_CPP__ */
